package com.lanyou.cook.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.kettle.KettleSlaveServer;
import com.lanyou.cook.repository.KettleSlaveServerRepository;
import com.lanyou.cook.service.KettleSlaveServerService;
import com.lanyou.cook.web.param.KettleSlaveParam;
import com.lanyou.esb.datadictionary.ForwardStatus;
import com.lanyou.esb.entity.ClusterNode;
import com.lanyou.esb.entity.StoreForward;
import com.lanyou.esb.repository.ClusterNodeRepository;
import com.lanyou.esb.web.RestAPI;

/**
 * kettle节点相关业务控制层
 * @author 仇伟业
 *
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/kettleSlaveServers")
public class KettleSlaveController{
	
	@Autowired
	private KettleSlaveServerService kettleSlaveServerService;
	@Autowired
	private KettleSlaveServerRepository kettleSlaveServerRepository;
	
	private Map<String, ClusterNode> nodeMap = new HashMap<>();
	
	@Autowired
	private ClusterNodeRepository clusterNodeRepository;
	
	private Map<String, KettleSlaveServer> nodeSlaveServerMap = new HashMap<String, KettleSlaveServer>();
	
	/**
	 * 查询特定条件下的kettle节点信息集合
	 * @param param	类型:KettleSlaveParam 待查询的kettle节点参数实体
	 * @param pageable 类型:Pageable 待查询的分页参数实体
	 * @return
	 */
	@RequestMapping("/search/findByExample")
	@RequiresPermissions(value={"nodeInformationOverView:view"})
	public List<KettleSlaveServer> findByExample(KettleSlaveParam param, Pageable pageable) {
		
		Specification<KettleSlaveServer> spec = new Specification<KettleSlaveServer>() {
			@Override
			public Predicate toPredicate(Root<KettleSlaveServer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicatesList = new ArrayList<>();
				if(StringUtils.isNotBlank(param.getName())){
					predicatesList.add(cb.like(root.get("name"), '%' + param.getName() + '%'));
				}
				query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
				return null;
			}
		};
		return kettleSlaveServerRepository.findAll();
	}
	
	/**
	 * 根据节点名称查询kettle节点信息
	 * @return 类型:String kettle节点信息
	 */
	@RequestMapping(value = "/search/findByName", produces="application/json")
	@RequiresPermissions(value={"nodeInformationOverView:view"})
	public Page<ClusterNode> findByName(String name,String ifRunning,Pageable pageable){
		if (name == null) {
			name = "";
		};
		List<Object[]> allServers = kettleSlaveServerRepository.findAllServer(name);
		List<Object[]> countAllServer = kettleSlaveServerRepository.countAllServer(name);
		List<ClusterNode> result = new ArrayList<ClusterNode>(countAllServer.size());
		int total = countAllServer.size();
		
		for (Object[] allServer : allServers) {
			ClusterNode clusterNode = new ClusterNode();
			clusterNode.setId(allServer[0] != null ? (String) allServer[0]: "");
			clusterNode.setName(allServer[1] != null ? (String) allServer[1]: "");
			clusterNode.setIpaddr(allServer[2] != null ? (String) allServer[2] : "");
			if(allServer[3].toString()!=""){
			int port = Integer.valueOf(allServer[3].toString()).intValue();
			clusterNode.setPort(port);
			};
			if(StringUtils.equals(allServer[4].toString(),"0")){
				clusterNode.setType("Kettle");
				long id = Long.valueOf(allServer[0].toString()).longValue();
			boolean running = kettleSlaveServerService.isRunning(id);
				if(running){
					clusterNode.setRemark("运行中");
				}else{
					clusterNode.setRemark("停止中");
				}
			}else{
				clusterNode.setType("cookESB");
				if(nodeMap == null || nodeMap.isEmpty()){	//如果缓存为空，将所有数据存入缓存
					if(nodeMap == null){
						nodeMap = new HashMap<>();
					}
					List<ClusterNode> list = clusterNodeRepository.findAll();
					for (ClusterNode clusterNode1 : list) {
						nodeMap.put(clusterNode1.getId(), clusterNode1);
					}
				}
				
				for (ClusterNode clusterNode1 : nodeMap.values()) {
					if(StringUtils.equals(clusterNode1.getName(),clusterNode.getName())){
						String flag = RestAPI.requestByGetMethod(clusterNode1.getIpaddr(), clusterNode1.getPort()+"" ,"NODE");
						if(!StringUtils.equals(flag, "false")){
							clusterNode.setRemark("运行中");
						}else{
							clusterNode.setRemark("停止中");
						}
					}
				}
			}
			if(ifRunning!=null){
				if(StringUtils.equals(clusterNode.getRemark(),ifRunning)){
					result.add(clusterNode);
					 total = result.size();
				}
			}else{
				result.add(clusterNode);
			}
		}
		
		
		Page<ClusterNode> page3 = new PageImpl<ClusterNode>(result, pageable, total);
		return page3;
	}
	
	/**
	 * 获取节点的的运行状态
	 * @return 类型:String 返回节点的运行状态
	 */
	@RequestMapping(value = "/runningStatus", produces="application/json")
	public String runningStatus(){
		if(nodeSlaveServerMap == null || nodeSlaveServerMap.isEmpty()){
			List<KettleSlaveServer> allSlaveServers = kettleSlaveServerRepository.findAll();
			for(KettleSlaveServer slaveServer : allSlaveServers){
				nodeSlaveServerMap.put(slaveServer.getName(), slaveServer);
			}
		}
		
		JsonArray isRuning = new JsonArray();
		JsonArray isNotRuning = new JsonArray();
		Set<String> keys = nodeSlaveServerMap.keySet();
		for (String key : keys) {
			boolean running = kettleSlaveServerService.isRunning(nodeSlaveServerMap.get(key).getId());
			if(running){
				isRuning.add(new JsonPrimitive(nodeSlaveServerMap.get(key).getId()));
			} else {
				isNotRuning.add(new JsonPrimitive(nodeSlaveServerMap.get(key).getId()));
			}
		}
		/*for(KettleSlaveServer slaveServer : allSlaveServers){
			boolean running = kettleSlaveServerService.isRunning(slaveServer.getId());
			if(running){
				isRuning.add(new JsonPrimitive(slaveServer.getId()));
			} else {
				isNotRuning.add(new JsonPrimitive(slaveServer.getId()));
			}
		}*/
		
		
		
		JsonObject resuslt = new JsonObject();
		resuslt.add("isRuning", isRuning);
		resuslt.add("isNotRuning", isNotRuning);
		return resuslt.toString();
	}
	
}